package net.suncaper.mvc.web.controller;

import net.suncaper.mvc.common.framework.simplemvc.RequestMapping;
import net.suncaper.mvc.common.utils.JSONUtil;
import net.suncaper.mvc.common.utils.Result;
import net.suncaper.mvc.model.domain.User;
import net.suncaper.mvc.model.vo.UserVO;
import net.suncaper.mvc.common.utils.EntityConverter;
import net.suncaper.mvc.service.IUserService;
import net.suncaper.mvc.service.impl.UserServiceImpl;
import net.suncaper.mvc.service.IRoleService;
import net.suncaper.mvc.service.impl.RoleServiceImpl;
import net.suncaper.mvc.service.IPermissionService;
import net.suncaper.mvc.service.impl.PermissionServiceImpl;
import net.suncaper.mvc.model.domain.Role;
import net.suncaper.mvc.model.domain.Permission;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.List;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.Cookie;
import net.suncaper.mvc.exception.BusinessException;
import net.suncaper.mvc.service.impl.UserServiceImpl;
import java.util.ArrayList;

/**
 * 用户控制层
 */
@RequestMapping("/api/user")
public class UserController {
    private IUserService userService = new UserServiceImpl();
    private IRoleService roleService = new RoleServiceImpl();
    private IPermissionService permissionService = new PermissionServiceImpl();

    /**
     * 用户注册
     */
    @RequestMapping("/register.do")
    public void register(HttpServletRequest request, HttpServletResponse response) {
        try {
            response.setHeader("Access-Control-Allow-Credentials", "true");
            response.setHeader("Access-Control-Allow-Origin", "http://localhost:3000");
            
            // 获取请求参数
            String email = request.getParameter("email");
            String password = request.getParameter("password");
            String avatar = request.getParameter("avatar");
            String genderStr = request.getParameter("gender");
            String ageStr = request.getParameter("age");
            String roleIdStr = request.getParameter("roleId");
            String hotelName = request.getParameter("hotelName");
            
            // 参数转换
            Integer gender = null;
            if (genderStr != null && !genderStr.isEmpty()) {
                try {
                    gender = Integer.parseInt(genderStr);
                } catch (NumberFormatException e) {
                    JSONUtil.printByJSON(response, Result.error("性别参数格式错误"));
                    return;
                }
            }
            
            Integer age = null;
            if (ageStr != null && !ageStr.isEmpty()) {
                try {
                    age = Integer.parseInt(ageStr);
                } catch (NumberFormatException e) {
                    JSONUtil.printByJSON(response, Result.error("年龄参数格式错误"));
                    return;
                }
            }
            
            Integer roleId = null;
            if (roleIdStr != null && !roleIdStr.isEmpty()) {
                try {
                    roleId = Integer.parseInt(roleIdStr);
                    // 注册时只能选择普通用户(1)或酒店商家(2)
                    if (roleId != 1 && roleId != 2) {
                        JSONUtil.printByJSON(response, Result.error("注册只能选择普通用户或酒店商家角色"));
                        return;
                    }
                } catch (NumberFormatException e) {
                    JSONUtil.printByJSON(response, Result.error("角色ID参数格式错误"));
                    return;
                }
            }
            
            // 调用注册服务
            User user = userService.register(email, password, avatar, gender, age, roleId, hotelName);
            
            // 注册成功，返回用户信息（不含密码）
            UserVO userVO = EntityConverter.convertToUserVO(user);
            
            // 创建登录会话
            HttpSession session = request.getSession();
            session.setAttribute("userId", user.getUserId());
            
            // 获取用户角色信息
            List<Role> roles = roleService.getUserRoles(user.getUserId());
            
            // 返回响应
            Map<String, Object> result = new HashMap<>();
            result.put("user", userVO);
            result.put("roles", roles);
            
            JSONUtil.printByJSON(response, Result.success(result, "注册成功"));
        } catch (BusinessException e) {
            JSONUtil.printByJSON(response, Result.error(e.getMessage()));
        } catch (Exception e) {
            e.printStackTrace();
            JSONUtil.printByJSON(response, Result.error("注册失败，系统异常"));
        }
    }

    /**
     * 创建用户（管理员功能）
     * 角色ID说明：1-普通用户，2-酒店商家，3-管理员
     */
    @RequestMapping("/create.do")
    public void createUser(HttpServletRequest request, HttpServletResponse response) {
        try {
            response.setHeader("Access-Control-Allow-Credentials", "true");
            response.setHeader("Access-Control-Allow-Origin", "http://localhost:3000");
            String userId = request.getParameter("userId");
            String email = request.getParameter("email");
            String password = request.getParameter("password");
            String roleIdStr = request.getParameter("roleId");
            String hotelName = null;
            
            // 将roleId转换为Integer
            Integer roleId = null;
            if (roleIdStr != null && !roleIdStr.isEmpty()) {
                try {
                    roleId = Integer.parseInt(roleIdStr);
                    // 验证角色ID是否有效
                    if (roleId < 1 || roleId > 3) {
                        JSONUtil.printByJSON(response, Result.error("无效的角色ID，有效值为：1-普通用户，2-酒店商家，3-管理员"));
                        return;
                    }
                } catch (NumberFormatException e) {
                    JSONUtil.printByJSON(response, Result.error("角色ID必须是数字"));
                    return;
                }
            }
            
            // 如果是酒店商家角色，则获取hotelName参数
            if (roleId != null && roleId == 2) {
                hotelName = request.getParameter("hotelName");
                
                // 增加对酒店商家的检查
                if (hotelName == null || hotelName.trim().isEmpty()) {
                    JSONUtil.printByJSON(response, Result.error("酒店商家必须提供酒店名称"));
                    return;
                }
            }

            User user = new User();
            user.setUserId(userId);
            user.setEmail(email);
            user.setPassword(password);

            // 创建用户并关联角色
            boolean result = ((UserServiceImpl)userService).createUserWithRole(user, roleId, hotelName);
            
            JSONUtil.printByJSON(response, Result.success(result));
        } catch (Exception e) {
            JSONUtil.printByJSON(response, Result.error(e.getMessage()));
        }
    }

    /**
     * 根据用户ID获取用户信息
     */
    @RequestMapping("/get.do")
    public void getUserById(HttpServletRequest request, HttpServletResponse response) {
        try {
            response.setHeader("Access-Control-Allow-Credentials", "true");
            response.setHeader("Access-Control-Allow-Origin", "http://localhost:3000");
            String userId = request.getParameter("userId");
            User user = userService.getUserById(userId);
            if (user != null) {
                UserVO userVO = EntityConverter.convertToUserVO(user);
                JSONUtil.printByJSON(response, Result.success(userVO));
            } else {
                JSONUtil.printByJSON(response, Result.error("用户不存在"));
            }
        } catch (Exception e) {
            JSONUtil.printByJSON(response, Result.error(e.getMessage()));
        }
    }

    /**
     * 用户登录
     */
    @RequestMapping("/login.do")
    public void login(HttpServletRequest request, HttpServletResponse response) {
        try {
            response.setHeader("Access-Control-Allow-Credentials", "true");
            response.setHeader("Access-Control-Allow-Origin", "http://localhost:3000");
            String email = request.getParameter("email");
            String password = request.getParameter("password");

            System.out.println("[UserController.login] 尝试登录: email=" + email);

            User user = userService.login(email, password);
            if (user != null) {
                // 登录成功，将用户ID存储在session中
                HttpSession session = request.getSession();
                session.setAttribute("userId", user.getUserId());
                
                System.out.println("[UserController.login] 登录成功，设置session: sessionId=" + session.getId() + ", userId=" + user.getUserId());
                
                // 显式设置Cookie的SameSite属性为None，并要求安全连接
                Cookie sessionCookie = new Cookie("JSESSIONID", session.getId());
                sessionCookie.setPath("/");
                // sessionCookie.setHttpOnly(true); // 该方法在较旧版本的Servlet API中不可用，移除
                // 注意：SameSite=None需要配合Secure使用，如果是HTTP连接需要使用Lax
                // sessionCookie.setSecure(true); // 如果是HTTPS，则开启此行
                response.addCookie(sessionCookie);
                
                // 获取用户角色信息
                List<Role> roles = roleService.getUserRoles(user.getUserId());
                
                // 创建用户登录响应信息
                Map<String, Object> loginInfo = new HashMap<>();
                loginInfo.put("user", EntityConverter.convertToUserVO(user));
                loginInfo.put("roles", roles);
                
                JSONUtil.printByJSON(response, Result.success(loginInfo));
            } else {
                JSONUtil.printByJSON(response, Result.error("邮箱或密码不正确"));
            }
        } catch (Exception e) {
            System.out.println("[UserController.login] 登录异常: " + e.getMessage());
            e.printStackTrace();
            JSONUtil.printByJSON(response, Result.error(e.getMessage()));
        }
    }
    
    /**
     * 获取当前登录用户信息
     */
    @RequestMapping("/current.do")
    public void getCurrentUser(HttpServletRequest request, HttpServletResponse response) {
        try {
            response.setHeader("Access-Control-Allow-Credentials", "true");
            response.setHeader("Access-Control-Allow-Origin", "http://localhost:3000");
            // 获取当前用户ID
            HttpSession session = request.getSession();
            String userId = (String) session.getAttribute("userId");
            
            System.out.println("[UserController.getCurrentUser] sessionId=" + session.getId());
            
            // 打印所有请求中的Cookie
            Cookie[] cookies = request.getCookies();
            if (cookies != null) {
                System.out.println("[UserController.getCurrentUser] 请求中的Cookies:");
                for (Cookie cookie : cookies) {
                    System.out.println("  " + cookie.getName() + "=" + cookie.getValue());
                }
            } else {
                System.out.println("[UserController.getCurrentUser] 请求中没有Cookie");
            }
            
            if (userId == null) {
                System.out.println("[UserController.getCurrentUser] 用户未登录，sessionId=" + session.getId());
                JSONUtil.printByJSON(response, Result.error("用户未登录"));
                return;
            }
            
            System.out.println("[UserController.getCurrentUser] 用户已登录，userId=" + userId);
            
            // 获取用户信息
            User user = userService.getUserById(userId);
            if (user == null) {
                JSONUtil.printByJSON(response, Result.error("用户不存在"));
                return;
            }
            
            // 获取用户角色和权限
            List<Role> roles = roleService.getUserRoles(userId);
            List<Permission> permissions = permissionService.getUserPermissions(userId);
            
            // 组装用户信息
            Map<String, Object> userInfo = new HashMap<>();
            userInfo.put("user", EntityConverter.convertToUserVO(user));
            userInfo.put("roles", roles);
            userInfo.put("permissions", permissions);
            
            JSONUtil.printByJSON(response, Result.success(userInfo));
        } catch (Exception e) {
            System.out.println("[UserController.getCurrentUser] 发生异常: " + e.getMessage());
            e.printStackTrace();
            JSONUtil.printByJSON(response, Result.error(e.getMessage()));
        }
    }
    
    /**
     * 用户退出登录
     */
    @RequestMapping("/logout.do")
    public void logout(HttpServletRequest request, HttpServletResponse response) {
        try {
            response.setHeader("Access-Control-Allow-Credentials", "true");
            response.setHeader("Access-Control-Allow-Origin", "http://localhost:3000");
            // 获取session并使其失效
            HttpSession session = request.getSession(false);
            if (session != null) {
                session.invalidate();
            }
            
            JSONUtil.printByJSON(response, Result.success("退出登录成功"));
        } catch (Exception e) {
            JSONUtil.printByJSON(response, Result.error(e.getMessage()));
        }
    }

    /**
     * 查询全部用户
     */
    @RequestMapping("/listAll.do")
    public void getAllUsers(HttpServletRequest request, HttpServletResponse response) {
        try {
            response.setHeader("Access-Control-Allow-Credentials", "true");
            response.setHeader("Access-Control-Allow-Origin", "http://localhost:3000");
            List<User> users = userService.getAllUsers();
            if (users != null && !users.isEmpty()) {
                List<UserVO> userVOList = EntityConverter.convertToUserVOList(users);
                
                // 增强返回数据：添加用户角色信息和酒店信息
                List<Map<String, Object>> enhancedUserList = new ArrayList<>();
                for (UserVO userVO : userVOList) {
                    Map<String, Object> enhancedUser = new HashMap<>();
                    enhancedUser.put("user", userVO);
                    
                    // 获取用户角色信息
                    String userId = userVO.getUserId();
                    List<Role> roles = roleService.getUserRoles(userId);
                    enhancedUser.put("roles", roles);
                    
                    // 获取用户角色ID
                    Integer roleId = userService.getUserRoleId(userId);
                    
                    // 如果是酒店商家（roleId=2），则获取酒店名称
                    if (roleId != null && roleId == 2) {
                        String hotelName = userService.getHotelName(userId);
                        enhancedUser.put("hotelName", hotelName);
                    }
                    
                    enhancedUserList.add(enhancedUser);
                }
                
                JSONUtil.printByJSON(response, Result.success(enhancedUserList));
            } else {
                JSONUtil.printByJSON(response, Result.error("暂无用户信息"));
            }
        } catch (Exception e) {
            JSONUtil.printByJSON(response, Result.error(e.getMessage()));
        }
    }

    /**
     * 更新用户角色
     * 请求参数：userId、roleId
     */
    @RequestMapping("/update.do")
    public void updateUser(HttpServletRequest request, HttpServletResponse response) {
        try {
            response.setHeader("Access-Control-Allow-Credentials", "true");
            response.setHeader("Access-Control-Allow-Origin", "http://localhost:3000");
            String userId = request.getParameter("userId");
            String roleIdStr = request.getParameter("roleId");      // 角色ID参数
            
            if (userId == null || userId.isEmpty()) {
                JSONUtil.printByJSON(response, Result.error("用户ID不能为空"));
                return;
            }
            
            // 将roleId转换为Integer
            Integer roleId = null;
            if (roleIdStr != null && !roleIdStr.isEmpty()) {
                try {
                    roleId = Integer.parseInt(roleIdStr);
                } catch (NumberFormatException e) {
                    JSONUtil.printByJSON(response, Result.error("角色ID必须是数字"));
                    return;
                }
            } else {
                JSONUtil.printByJSON(response, Result.error("角色ID不能为空"));
                return;
            }
            
            try {
                // 查询现有用户信息
                User existingUser = userService.getUserById(userId);
                if (existingUser == null) {
                    JSONUtil.printByJSON(response, Result.error("用户不存在，请检查用户ID是否正确"));
                    return;
                }
                
                // 使用现有用户信息构建更新对象
                User user = new User();
                user.setUserId(userId);
                user.setEmail(existingUser.getEmail()); // 保持邮箱不变
                user.setPassword(existingUser.getPassword()); // 保持密码不变
                user.setAvatar(existingUser.getAvatar());
                user.setStatus(existingUser.getStatus());
                user.setGender(existingUser.getGender());
                user.setAge(existingUser.getAge());
                user.setCreateTime(existingUser.getCreateTime());
                
                // 更新用户角色
                boolean result = ((UserServiceImpl)userService).updateUserWithRole(user, roleId, null);
                
                JSONUtil.printByJSON(response, Result.success(result, "用户角色更新成功"));
            } catch (Exception e) {
                System.out.println("[UserController.updateUser] 更新失败: " + e.getMessage());
                JSONUtil.printByJSON(response, Result.error("更新角色失败: " + e.getMessage()));
                return;
            }
        } catch (Exception e) {
            System.out.println("[UserController.updateUser] 异常: " + e.getMessage());
            JSONUtil.printByJSON(response, Result.error(e.getMessage()));
        }
    }

    /**
     * 更新用户个人信息
     */
    @RequestMapping("/updateProfile.do")
    public void updateUserProfile(HttpServletRequest request, HttpServletResponse response) {
        try {
            response.setHeader("Access-Control-Allow-Credentials", "true");
            response.setHeader("Access-Control-Allow-Origin", "http://localhost:3000");
            
            // 验证用户是否已登录
            HttpSession session = request.getSession();
            String userId = (String) session.getAttribute("userId");
            
            if (userId == null) {
                JSONUtil.printByJSON(response, Result.error("用户未登录"));
                return;
            }
            
            // 获取参数
            String newUserId = request.getParameter("newUserId");
            String avatar = request.getParameter("avatar");
            String genderStr = request.getParameter("gender");
            String ageStr = request.getParameter("age");
            
            // 参数转换
            Integer gender = null;
            if (genderStr != null && !genderStr.isEmpty()) {
                try {
                    gender = Integer.parseInt(genderStr);
                    // 验证性别值是否有效 (0-女，1-男，2-保密)
                    if (gender < 0 || gender > 2) {
                        JSONUtil.printByJSON(response, Result.error("无效的性别值，有效值为：0-女，1-男，2-保密"));
                        return;
                    }
                } catch (NumberFormatException e) {
                    JSONUtil.printByJSON(response, Result.error("性别参数格式错误"));
                    return;
                }
            }
            
            Integer age = null;
            if (ageStr != null && !ageStr.isEmpty()) {
                try {
                    age = Integer.parseInt(ageStr);
                    // 验证年龄是否合理
                    if (age < 0 || age > 120) {
                        JSONUtil.printByJSON(response, Result.error("请输入合理的年龄值(0-120)"));
                        return;
                    }
                } catch (NumberFormatException e) {
                    JSONUtil.printByJSON(response, Result.error("年龄参数格式错误"));
                    return;
                }
            }
            
            // 调用服务更新用户信息
            User updatedUser = userService.updateUserProfile(userId, newUserId, avatar, gender, age);
            
            // 如果修改了用户ID，需要更新会话中的用户ID
            if (newUserId != null && !newUserId.isEmpty() && !newUserId.equals(userId)) {
                session.setAttribute("userId", newUserId);
            }
            
            // 转换为VO并返回
            UserVO userVO = EntityConverter.convertToUserVO(updatedUser);
            
            JSONUtil.printByJSON(response, Result.success(userVO, "个人信息更新成功"));
            
        } catch (BusinessException e) {
            JSONUtil.printByJSON(response, Result.error(e.getMessage()));
        } catch (Exception e) {
            e.printStackTrace();
            JSONUtil.printByJSON(response, Result.error("更新个人信息失败，系统异常"));
        }
    }

    /**
     * 删除用户
     * 请求参数：userId
     */
    @RequestMapping("/delete.do")
    public void deleteUser(HttpServletRequest request, HttpServletResponse response) {
        try {
            response.setHeader("Access-Control-Allow-Credentials", "true");
            response.setHeader("Access-Control-Allow-Origin", "http://localhost:3000");
            String userId = request.getParameter("userId");
            boolean result = userService.deleteUser(userId);
            JSONUtil.printByJSON(response, Result.success(result));
        } catch (Exception e) {
            JSONUtil.printByJSON(response, Result.error(e.getMessage()));
        }
    }

    /**
     * 获取当前用户个人信息
     */
    @RequestMapping("/profile.do")
    public void getUserProfile(HttpServletRequest request, HttpServletResponse response) {
        try {
            response.setHeader("Access-Control-Allow-Credentials", "true");
            response.setHeader("Access-Control-Allow-Origin", "http://localhost:3000");
            
            // 验证用户是否已登录
            HttpSession session = request.getSession();
            String userId = (String) session.getAttribute("userId");
            
            if (userId == null) {
                JSONUtil.printByJSON(response, Result.error("用户未登录"));
                return;
            }
            
            // 查询用户信息
            User user = userService.getUserById(userId);
            if (user == null) {
                JSONUtil.printByJSON(response, Result.error("用户不存在"));
                return;
            }
            
            // 查询用户角色信息
            List<Role> roles = roleService.getUserRoles(userId);
            
            // 查询用户所属酒店名称（如果是酒店商家）
            String hotelName = userService.getHotelName(userId);
            
            // 转换为VO
            UserVO userVO = EntityConverter.convertToUserVO(user);
            
            // 组装结果
            Map<String, Object> result = new HashMap<>();
            result.put("user", userVO);
            result.put("roles", roles);
            if (hotelName != null) {
                result.put("hotelName", hotelName);
            }
            
            JSONUtil.printByJSON(response, Result.success(result));
            
        } catch (BusinessException e) {
            JSONUtil.printByJSON(response, Result.error(e.getMessage()));
        } catch (Exception e) {
            e.printStackTrace();
            JSONUtil.printByJSON(response, Result.error("获取个人信息失败，系统异常"));
        }
    }
}    